package com.mask.sms.service.impl;

import com.mask.roll.common.code.ServiceEnums;
import com.mask.roll.common.code.SystemEnums;
import com.mask.roll.common.code.ThirdEnums;
import com.mask.roll.common.constant.RollConstants;
import com.mask.roll.common.exception.RollException;
import com.mask.roll.common.util.RollResponse;
import com.mask.sms.service.SmsService;
import com.mask.sms.util.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author hx
 */
@Service
@Slf4j
public class SmsServiceImpl implements SmsService {

    @Autowired
    public RedisTemplate<String,String> redisTemplate;

    @Override
    public RollResponse send(String phone) {

        String host = "https://dfsns.market.alicloudapi.com";
        String path = "/data/send_sms";
        String method = "POST";
        String appcode = "03cfc44b348242188154f2af5ded9c40";
        Map<String, String> headers = new HashMap<String, String>();
        //生成6位数验证码
        String code = String.valueOf((int)((Math.random() * 9 + 1) * Math.pow(10,5)));
        headers.put("Authorization", "APPCODE " + appcode);
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("content", "code:"+code+",time:1");
        bodys.put("phone_number", phone);
        bodys.put("template_id", "ROLL_0001");
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            StatusLine statusLine = response.getStatusLine();
            //响应码200正常,400验证码错误,403调用次数用完,500服务器内部错误
            int status = statusLine.getStatusCode();
            System.out.println(status);
            switch (status) {
                case 200:
                    try {
                        this.redisTemplate.opsForValue().set(RollConstants.REDIS_PHONE_PREFIX+phone,code,1L,TimeUnit.MINUTES);
                    } catch (Exception e) {
                        log.error("redis异常:{}",e.getMessage());
                        throw new RollException(SystemEnums.REDIS_ERROR.getCode(),
                                RollConstants.ERROR,SystemEnums.SYSTEM_ERROR.getMessage());
                    }
                    log.info("手机{}短信发送成功:{}",phone,code);
                return RollResponse.result(ThirdEnums.SMS_NORMAL.getCode(),
                        RollConstants.SUCCESS,ThirdEnums.SMS_SEND_SUCCESS.getMessage(),code);

                case 400:
                    return RollResponse.result(ThirdEnums.SMS_INVALID_ARGUMENT.getCode(),RollConstants.ERROR,
                            ThirdEnums.SMS_INVALID_ARGUMENT.getMessage());
                case 401:
                    return RollResponse.result(ThirdEnums.SMS_UNAUTHORIZED.getCode(),RollConstants.ERROR,
                            ThirdEnums.SMS_UNAUTHORIZED.getMessage());
                case 403:
                    return RollResponse.result(ThirdEnums.SMS_RATE_LIMIT_EXCEEDED.getCode(),RollConstants.ERROR,
                            ThirdEnums.SMS_RATE_LIMIT_EXCEEDED.getMessage());
                case 512:
                    return RollResponse.result(ThirdEnums.SMS_SOURCE_SERVICE_UNAVALIABLE.getCode(),
                            RollConstants.ERROR, ThirdEnums.SMS_SOURCE_SERVICE_UNAVALIABLE.getMessage());
                default:
                    return RollResponse.result(SystemEnums.SYSTEM_ERROR.getCode(),
                            RollConstants.ERROR, SystemEnums.SYSTEM_ERROR.getMessage());
            }

        } catch (Exception e) {
            log.error("发送短信异常:{}",e.getMessage());
            throw new RollException(SystemEnums.SYSTEM_ERROR.getCode(),
                    RollConstants.ERROR,SystemEnums.SYSTEM_ERROR.getMessage());
        }
    }

    @Override
    public RollResponse checkCode(String phone, String code) {
        Boolean hasKey = null;
        try {
            hasKey = this.redisTemplate.hasKey(RollConstants.REDIS_PHONE_PREFIX + phone);
        } catch (Exception e) {
            log.error("redis异常:{}",e.getMessage());
            throw new RollException(SystemEnums.REDIS_ERROR.getCode(),
                    RollConstants.ERROR,SystemEnums.SYSTEM_ERROR.getMessage());
        }

        //判断code是否存在
        if (!hasKey) {
            log.info("手机号{}未发送验证码",phone);
            return RollResponse.result(ServiceEnums.SMS_CODE_NO_EXIST.getCode(),
                    RollConstants.ERROR,ServiceEnums.SMS_CODE_NO_EXIST.getMessage());
        }
        Long expireKey = null;
        try {
            expireKey = this.redisTemplate.opsForValue().getOperations().getExpire(
                    RollConstants.REDIS_PHONE_PREFIX + phone);
        } catch (Exception e) {
            log.error("redis异常:{}",e.getMessage());
            throw new RollException(SystemEnums.REDIS_ERROR.getCode(),
                    RollConstants.ERROR,SystemEnums.SYSTEM_ERROR.getMessage());
        }
        //判断code是否过期
        if (expireKey < -1) {
            log.info("手机号{}的验证码{}已过期",phone,code);
            return RollResponse.result(ServiceEnums.SMS_CODE_EXPIRE.getCode(),
                    RollConstants.ERROR,ServiceEnums.SMS_CODE_EXPIRE.getMessage());
        }
        String redisCode = this.redisTemplate.opsForValue().get(
                RollConstants.REDIS_PHONE_PREFIX + phone);

        //判断验证码是否正确
        if (hasKey && expireKey > -2 && !redisCode.equals(code)) {
            log.info("手机号{}验证码{}不匹配",phone,code);
            return RollResponse.result(ServiceEnums.SMS_CODE_NO_MATCH.getCode(),
                    RollConstants.ERROR,ServiceEnums.SMS_CODE_NO_MATCH.getMessage());
        }else {
            log.info("手机号{}验证码{}验证成功",phone,code);
            return RollResponse.result(ServiceEnums.SMS_CODE_MATCH.getCode(),
                    RollConstants.SUCCESS,ServiceEnums.SMS_CODE_MATCH.getMessage());
        }
    }
}
